package com.xuantu.pattern.create.factory;

/**
 * 抽象工厂
 * 意图：提供一个创建一系列相关或相互依赖对象的接口，而无需指定他们的实现类。
 * 
 * 与工厂方法不同，工厂方法中有多个抽象方法，生成不同的对象实例
 * 
 * @author fengzp
 *
 */
public class AbstractFactory {
	
	/**
	 * 小部件工厂
	 * @author fengzp
	 *
	 */
	abstract class WidgetFactory {
		
		abstract Window createWindow();
		
		abstract ScrollBar createScrollBar();
		
	}
	
	/**
	 * PM风格工厂
	 * @author fengzp
	 *
	 */
	class PMWidgetFactory extends WidgetFactory{

		@Override
		Window createWindow() {
			return new PMWindow();
		}

		@Override
		ScrollBar createScrollBar() {
			return new PMScrollBar();
		}
		
	}
	
	/**
	 * Modify风格工厂
	 * @author fengzp
	 *
	 */
	class ModifyWidgetFactory extends WidgetFactory{

		@Override
		Window createWindow() {
			return new ModifyWindow();
		}

		@Override
		ScrollBar createScrollBar() {
			return new ModifyScrollBar();
		}
		
	}
	
	
	
	/**
	 * 窗口
	 * @author fengzp
	 *
	 */
	interface Window {
		void show();
	}
	
	/**
	 * PM风格的窗口
	 * @author fengzp
	 *
	 */
	class PMWindow implements Window {

		@Override
		public void show() {
			System.out.println("I'm PM style window!");
		}
		
	}
	
	/**
	 * Modify风格的窗口
	 * @author fengzp
	 *
	 */
	class ModifyWindow implements Window {
		@Override
		public void show() {
			System.out.println("I'm Modify style window!");
		}
	}
	
	/**
	 * 滚动条
	 * @author fengzp
	 *
	 */
	interface ScrollBar {
		void show();
	}
	
	/**
	 * PM风格的滚动条
	 * @author fengzp
	 *
	 */
	class PMScrollBar implements ScrollBar {
		@Override
		public void show() {
			System.out.println("I'm PM style scrollbar!");
		}
	}
	
	/**
	 * Modify风格的滚动条
	 * @author fengzp
	 *
	 */
	class ModifyScrollBar implements ScrollBar {
		@Override
		public void show() {
			System.out.println("I'm Modify style scrollbar!");
		}
	}
	
	/**
	 * 客户端
	 * @param args
	 */
	public static void main(String[] args) {
		WidgetFactory factory = new AbstractFactory().new PMWidgetFactory();
		
		Window window = factory.createWindow();		
		ScrollBar scrollbar = factory.createScrollBar();
		
		window.show();
		scrollbar.show();
		
	}

}
